home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
United Public Domain Gold 4
/
United Public Domain Gold 4.iso
/
scope
/
sc093.dms
/
sc093.adf
/
LM
/
lm2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-02
|
7KB
|
394 lines
#include <stdio.h>
#include "lm.h"
extern long in_file, out_file;
extern char *get_next_file(), *in_file_name;
extern BOOL same_output_file;
struct symbol *sym_list_head, *sym_ptr;
extern long mod_buf[MBUF_SIZE];
int eolib, symbol_offset;
unsigned long buf_count, old_buf_count, current_long, temp;
void *AllocMem();
long Open(), Write();
/* --------------------------------------------------------------------------
STRIP_LIBRARY ROUTINES
---------------------------------------------------------------------------*/
strip_library()
{
/*
Read through the library and discard the symbol and debug
hunks.
*/
unsigned module_size;
unsigned long end_o_hunk = HUNK_END;
printf( ">> Stripping: <%s>\n",in_file_name );
while( (module_size = read_lib_module() ) )
{
/*
Strip symbol/debug hunks if there. All we do is write
back the module up to the symbol/debug hunk and stick
a HUNK_END on the end.
*/
if ( symbol_offset )
{
Write( out_file, mod_buf, (long) (symbol_offset << 2) );
Write( out_file, &end_o_hunk, 4L );
}
else
{
Write( out_file, mod_buf, (long) (module_size << 2) );
}
}
}
/* --------------------------------------------------------------------------
ADD_MODULE ROUTINES
---------------------------------------------------------------------------*/
add_modules( file_list )
char *file_list;
{
char *p;
long fp;
unsigned long longword;
copy_lib( in_file, out_file );
while( (p = get_next_file( file_list ) ) )
{
if ( !(fp = Open( p, MODE_OLDFILE ) ) )
{
printf( "ERROR: Object file: <%s> not found\n", p );
}
else
{
printf( ">> Adding: <%s>\n", p );
copy_lib( fp, out_file );
Close( fp );
}
}
}
add_symbol( sym_name )
char *sym_name;
{
/*
Add the symbol in sym_name to the list of symbols.
*/
struct symbol *p;
if(!(p=(struct symbol*)AllocMem((long)sizeof(struct symbol), 0L)))
{
my_exit( ENOMEM );
}
p->next = NULL;
sym_ptr->next = p;
sym_ptr = p;
strcpy( sym_ptr->name, sym_name );
}
get_and_put()
{
/*
Fetch a longword from the input file, stick it in the module
buffer, and return it. Return NULL if no more to read.
*/
long longword;
/*
First, make sure we are not overwriting innocent ram!
*/
if ( buf_count > MBUF_SIZE )
{
my_exit( ENOBUF );
}
if ( eolib ) /* End of library? */
{
my_exit( EOLIB );
}
if ( !GetLongword( in_file, &longword ) )
{
eolib = TRUE;
return( TRUE );
}
mod_buf[buf_count++] = longword;
current_long = longword;
return( TRUE );
}
read_lib_module()
{
/*
Read in the next module from the library, if one exists, and
stick all the XDEF symbols in the symbol list. Return either
the number of longwords in the module or 0 to indicate the
end of the library.
*/
clear_sym_list(); /* clean out prev sym list */
sym_ptr = sym_list_head; /* Reset sym ptr */
symbol_offset = 0; /* Clear offset of symbol hunk ptr */
buf_count = 0; /* Nothing in the buffer... */
eolib = 0; /* Not at end-of-library yet */
while( get_and_put() )
{
if ( eolib )
return( 0 );
switch( current_long )
{
case HUNK_UNIT :
case HUNK_NAME : get_named_hunk();
break;
case HUNK_CODE :
case HUNK_DATA : get_code_data_debug_hunk();
break;
case HUNK_DEBUG : if ( !symbol_offset )
symbol_offset = buf_count-1;
get_code_data_debug_hunk();
break;
case HUNK_BSS : get_and_put();
break;
case HUNK_RELOC32:
case HUNK_RELOC16:
case HUNK_RELOC8 : get_reloc_hunk();
break;
case HUNK_SYMBOL : get_symbol_hunk();
break;
case HUNK_EXT : get_public_symbols();
break;
case HUNK_END : return( buf_count );
break;
}
}
}
get_public_symbols()
{
/*
Stick the XDEF symbols in the HUNK_EXT hunk in the symbol
list.
*/
unsigned long size, ref_count, name_buf[10], i;
unsigned char type;
get_and_put(); /* read first symbol data unit */
while ( current_long ) /* repeat til 0 */
{
size = current_long & 0xffffff; /* Strip type field */
type = current_long >> 24;
for ( i = 0; i < size; i++ )
{
get_and_put();
name_buf[i] = current_long;
}
name_buf[size] = '\0'; /* null term the string */
switch( type )
{
case ext_symb :
case ext_def :
case ext_abs :
/* Eat the Offset longword */
case ext_res : get_and_put();
add_symbol( name_buf );
break;
/*
The rest of this switch statement just eats the infor-
mation contained in the hunk because we don't need it.
*/
case ext_ref32 : goto skip;
case ext_common : /* The next field is the size field */
get_and_put();
skip: case ext_ref16 : /* Eat the ref count and the ref
offset fields */
case ext_ref8 : get_and_put();
ref_count = current_long;
for ( i = 0; i < ref_count; i++ )
get_and_put();
break;
}
get_and_put();
}
}
get_named_hunk()
{
/*
Read in the named hunk (HUNK_NAME/HUNK_UNIT).
*/
register int i;
get_and_put();
temp = current_long;
for( i = 0; i < temp; i++ )
{
get_and_put();
}
}
get_code_data_debug_hunk()
{
/*
Read in the CODE, DATA or DEBUG hunk.
*/
register int i;
get_and_put();
temp = current_long;
for ( i = 0; i < temp; i++ )
get_and_put();
}
get_reloc_hunk()
{
/*
Eat the info in the relocxx hunks.
*/
register int i;
unsigned long relocs;
get_and_put();
while( current_long )
{
relocs = current_long;
get_and_put();
for( i = 0; i < relocs; i++ )
get_and_put();
get_and_put();
}
}
get_symbol_hunk()
{
/*
Chew through the symbol hunk.
*/
unsigned long ext_id;
unsigned int i;
/*
Mark the place where the symbol hunk begins.
*/
symbol_offset = buf_count-1;
get_and_put();
while ( current_long )
{
ext_id = current_long;
for ( i = 0; i <= ext_id; i++ )
get_and_put();
get_and_put();
}
}
clear_sym_list()
{
/*
Destroy the symbol list if one exists, but leave the head node
intact for future use and abuse.
*/
struct symbol *p, *q = sym_list_head->next;
while ( q )
{
p = q->next;
FreeMem( q, (long) sizeof( struct symbol ) );
q = p;
}
sym_list_head->next = NULL;
}
copy_lib( in_file, out_file )
long in_file, out_file;
{
char *p;
long count, Read();
if ( !( p = AllocMem( READBUFSIZE, 0L ) ) )
{
my_exit( ENOMEM );
}
while( ( count = Read( in_file, p, READBUFSIZE ) ) )
{
Write( out_file, p, count );
}
FreeMem( p, READBUFSIZE );
}